// -----------------------------------------------------------------------
//  <copyright file="SettingItem.cs" company="LiuliuSoft">
//      Copyright (c) 2022-2024 DaprPlus. All rights reserved.
//  </copyright>
//  <site>https://www.dapr.plus</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2024-04-15 20:47</last-date>
// -----------------------------------------------------------------------

using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics;

using DaprPlus.Domain.Entity;
using DaprPlus.Properties;

using OSharp.Localized;


namespace DaprPlus.Settings.Domain.Entities;

[DebuggerDisplay("{Key}: {Value}")]
[LocalizedDescription("String_Settings_SettingItem", typeof(ResDaprPlus))]
public class SettingItem : EntityBase, ISettingItem
{
    public SettingItem()
    { }

    public SettingItem(string key, object? value)
    {
        Key = key;
        Value = value;
    }

    /// <summary>
    /// 获取或设置 设置键，使用复合键设计，比如 ServiceName:Environment:Key，以区分不同服务和不同环境的配置
    /// </summary>
    public string Key { get; set; } = null!;

    /// <summary>
    /// 获取或设置 数据值的JSON
    /// </summary>
    public string? ValueJson { get; set; }

    /// <summary>
    /// 获取或设置 数据值
    /// </summary>
    [NotMapped]
    public object? Value
    {
        get
        {
            if (string.IsNullOrEmpty(ValueJson) || string.IsNullOrEmpty(ValueTypeName))
            {
                return null;
            }
            var type = Type.GetType(ValueTypeName) ?? throw new DaprPlusException(ResDaprPlus.Format_SettingItem_Type_NotFound.FormatWith(Key, ValueTypeName));
            return ValueJson.FromTextJson(type);
        }
        set
        {
            ValueTypeName ??= value?.GetType().GetFullNameWithModule();
            ValueJson = value?.ToTextJson();
        }
    }

    /// <summary>
    /// 获取或设置 数据值的类型名
    /// </summary>
    public string? ValueTypeName { get; set; }

    /// <summary>
    /// 获取或设置 显示名
    /// </summary>
    public string? Display { get; set; }

    /// <summary>
    /// 获取或设置 备注
    /// </summary>
    public string? Remark { get; set; }

    /// <summary>
    /// 获取或设置 顺序
    /// </summary>
    public int Order { get; set; }

    /// <summary>
    /// 获取或设置 是否锁定
    /// </summary>
    public bool IsLocked { get; set; }

    public DateTime LastUpdatedTime { get; set; }

    public long SettingDefinitionId { get; set; }

    public SettingDefinition SettingDefinition { get; set; } = null!;

    /// <summary>
    /// 获取强类型数据值
    /// </summary>
    /// <typeparam name="T">强类型</typeparam>
    /// <returns></returns>
    public T? GetValue<T>()
    {
        var value = Value;
        if (Equals(value, default(T)))
        {
            return default;
        }

        if (value is T val)
        {
            return val;
        }

        try
        {
            return value.CastTo<T>();
        }
        catch (Exception)
        {
            throw new DaprPlusException(
                ResDaprPlus.Format_SettingItem_ValueConvertFail.FormatWith(Key, typeof(T).FullName, ValueTypeName));
        }
    }

}

[NotMapped]
public class SettingItem<T> : SettingItem
{
    public SettingItem()
    {
        ValueTypeName = typeof(T).GetFullNameWithModule();
    }

    public SettingItem(string key, T value) : base(key, value)
    {
        Value = value;
        ValueTypeName = typeof(T).GetFullNameWithModule();
    }

    [NotMapped]
    public new T? Value
    {
        get
        {
            var value = base.Value;
            if (value == null)
            {
                return default;
            }

            if (value is T tValue)
            {
                return tValue;
            }

            try
            {
                return (T)Convert.ChangeType(value, typeof(T));
            }
            catch (Exception ex)
            {
                throw new InvalidCastException(ResDaprPlus.Format_SettingItemT_ValueConvertFail.FormatWith(typeof(T).FullName), ex);
            }
        }
        set => base.Value = value;
    }
}
